package com.yy.loramodule;

import android.graphics.Color;
import android.os.Build;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
import android.util.Log;

import com.run.serial.ConvertData;
import com.run.serial.RxDataCallBack;
import com.run.serial.SerialUtils;

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashMap;

public class LoraSensor implements RxDataCallBack {
    public static final String TAG = "LoraSensor";

	private static LoraSensor ourInstance = null;

	int sendPkgNum = 0;
	int recvPkgNum = 0;

    private LoraSensor() {
    }

	public static LoraSensor getInstance() {
		if (null == ourInstance) {
			synchronized (LoraSensor.class) {
				if (null == ourInstance) {
					ourInstance = new LoraSensor();
				}
			}
		}
		return ourInstance;
	}

	//1窄带自组网接口
	//1.1查询状态
	public boolean wirelessWorkEnable() {
		return SerialUtils.getInstance().isOpenSuccess();
	}
	
	//1.2设置参数
	public static class WirelessParameter {
		int frequency;
		int spreadingFactor;
		int bandWidth;
		int power;
		int address;
		int[] groupAddress;
		boolean forward;
		int sleepPercent;
	}
	SetParameterListener mSetParameterListener;
	//回调类定义
	public interface SetParameterListener {
		void isSetParameterSuccessful(boolean state);
	}
	
	public void setWirelessParameter(WirelessParameter wirelessParameter, SetParameterListener callback) {
		mSetParameterListener = callback;
		StringBuilder cmd = new StringBuilder();
		cmd.append("at+set=");
		cmd.append("freq ").append(wirelessParameter.frequency).append(" ");
		cmd.append("key 1234567890aabbcc1234567890aabbcc sf ").append(wirelessParameter.spreadingFactor).append(" ");
		cmd.append("bw ").append(wirelessParameter.bandWidth).append(" ");
		cmd.append("power ").append(wirelessParameter.power).append(" ");
		cmd.append("id ").append(wirelessParameter.address).append(" ");
		cmd.append("relay ").append(wirelessParameter.forward ? "on":"off").append(" ");
		cmd.append("slr ").append(wirelessParameter.sleepPercent).append(" ");
		if (wirelessParameter.groupAddress.length > 0) {
			cmd.append("group");
		}
		for (int i = 0; i < wirelessParameter.groupAddress.length; i++) {
			cmd.append(" ").append(wirelessParameter.groupAddress[i]);
		}
		cmd.append("\r\n");

		String a = new String(cmd.toString().getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
		Logger.d("setWirelessParameter cmd++" + cmd.toString() + "++a||" + a + "||end");//str.getBytes("GBK");

		SerialUtils.getInstance().sendPackage(cmd.toString().getBytes(StandardCharsets.UTF_8));
//		SerialUtils.getInstance().sendPackage("at+save\r\n".getBytes(StandardCharsets.UTF_8));
//		SerialUtils.getInstance().sendPackage("at+reset\r\n".getBytes(StandardCharsets.UTF_8));
//		SerialUtils.getInstance().sendPackage("at+set\r\n".getBytes(StandardCharsets.UTF_8));
	}

	//1.3发送消息
	public static class SendMessage {
		int ack;
		int seqNo;
		int msgType;
		int nodeAddress;
		int targatAddress;
		int forwardNum;
		byte[] content;//32所定义所有数据类型和结构
	}

	SendMessageListener mSendMessageListener;
	public interface SendMessageListener {
		void isSendMessageSuccesful(boolean state);
	}
	
	public void sendMsg(SendMessage msg, SendMessageListener sendMessageListener) {
		mSendMessageListener = sendMessageListener;

		StringBuilder cmd = new StringBuilder();
		cmd.append("at+start=");
		cmd.append(msg.ack == 0 ? "0" : msg.seqNo + "").append(" ");//0为不应答，1为需要应答
		if (msg.msgType == 0) {//0为组播，1为单播
			cmd.append("bc to ").append(msg.targatAddress).append(" ");
		} else if (msg.msgType == 1) {
			cmd.append("uc to ").append(msg.targatAddress).append(" ");
		}
		cmd.append("ttl ").append(msg.forwardNum).append(" ");
		if (msg.content.length > 0) {
			cmd.append("hex ");
		}
		for (int i = 0; i < msg.content.length; i++) {
			cmd.append(String.format("%02X", msg.content[i]));
		}
		cmd.append("\r\n");

		String a = new String(cmd.toString().getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
		Logger.d("sendMsg cmd++" + cmd.toString() + "++a||" + a + "||end");//str.getBytes("GBK");

		SerialUtils.getInstance().sendPackage(cmd.toString().getBytes(StandardCharsets.UTF_8));
		sendPkgNum++;
		if ( loraDataListener != null ) {
			loraDataListener.loraDataRTNum(sendPkgNum, recvPkgNum);
		}
//		SerialUtils.getInstance().sendPackage(("at+stop " + msg.seqNo + "\r\n").getBytes(StandardCharsets.UTF_8));
//		SerialUtils.getInstance().sendPackage(("at+sleep" + "\r\n").getBytes(StandardCharsets.UTF_8));
	}

	//1.4接收消息
	public class RecvMessage {
		int msgType;
		int seqNo;
		int nodeAddress;
		int targatAddress;
		int forwardNum;
		byte[] content;
	}

	MessageListener mMessageListener;
	public interface MessageListener {
		void receiveMsg(RecvMessage msg);
		void receiveStr(String msg);
	}
	
	public void registerMsg(MessageListener messageListener) {
		mMessageListener = messageListener;
	}


	//2传感器接口
	//2.1控制接口回调接口定义
	public interface DeviceOperationListener {
		void isDeviceOperationSuccessful(boolean state);
	}
	
	//开启窄带自组网
	void openLoRa(DeviceOperationListener deviceOperationListener) {
		boolean ret = SerialUtils.getInstance().init(115200, "/dev/ttyS1");//ttyS1->sl8541e ttyS2--> 7885
		SerialUtils.getInstance().startTask();
		SerialUtils.getInstance().regRxDataCallBack(this);
		deviceOperationListener.isDeviceOperationSuccessful(ret);
	}
	
	//关闭窄带自组网
	void closeLoRa(DeviceOperationListener deviceOperationListener) {
		boolean ret = SerialUtils.getInstance().stopSerial();
		deviceOperationListener.isDeviceOperationSuccessful(ret);
	}
	
	//开启心率血氧传感器
	void openHRT(DeviceOperationListener deviceOperationListener) {
	}
	
	//关闭心率血氧传感器
	void closeHRT(DeviceOperationListener deviceOperationListener) {
	}
	
	//开启体温传感器
	void openTS(DeviceOperationListener deviceOperationListener) {
	}
	//关闭体温传感器
	void closeTS(DeviceOperationListener deviceOperationListener) {
	}
	//开启血压传感器
	void openBP(DeviceOperationListener deviceOperationListener) {
	}
	
	//开启血压传感器
	void closeBP(DeviceOperationListener deviceOperationListener) {
	}
	
	//2.2传感器接口 读取数据
	//数据回调接口
	public SensorDataListener mSensorDataListener;
	public interface SensorDataListener {
		void sensorDataCallback(byte[] data);
	}
	public void registerSensorDataListener(SensorDataListener sensorDataListener) {
		mSensorDataListener = sensorDataListener;
	}




	@Override
	public void sendData(byte[] data, int len) {
	}

	@Override
	public void onSucceed(String origin, byte[] data, int len) {
		if (len > 0) {
			String recvData = new String(data, StandardCharsets.UTF_8);
			if (mMessageListener != null) {
				mMessageListener.receiveStr(recvData);
			}
			Logger.d("onSucceed send " + origin + " recv :" + recvData + ":end");
			if ( origin.contains("at+set=") && mSetParameterListener != null) {
				mSetParameterListener.isSetParameterSuccessful(recvData.contains("OK"));
			}
			if ( origin.contains("at+start=") && mSendMessageListener != null) {
				mSendMessageListener.isSendMessageSuccesful(recvData.contains("OK"));
			
			}
			if ( recvData.contains("!STOP") && mMessageListener != null) {
				String[] items = recvData.split(" "); // 使用空格作为分隔符拆分字符串
				Logger.d("onSucceed !STOP " + findItemStr(items, "!STOP", false));
				RecvMessage msgStop = new RecvMessage();
				mMessageListener.receiveMsg(msgStop);
			}
			if ( recvData.contains("!RX") && mMessageListener != null) {

				recvPkgNum++;
				if ( loraDataListener != null ) {
					loraDataListener.loraDataRTNum(sendPkgNum, recvPkgNum);
				}

				RecvMessage msgRx = new RecvMessage();
				if (recvData.startsWith("!RX BC")) {
					msgRx.msgType = 0;
				} else if (recvData.startsWith("!RX UC")) {
					msgRx.msgType = 1;
				}
				String[] items = recvData.split(" "); // 使用空格作为分隔符拆分字符串
				msgRx.nodeAddress = Integer.parseInt(findItemStr(items, "NODE", false));
				msgRx.targatAddress = Integer.parseInt(findItemStr(items, "TO", false));
				String ttl = findItemStr(items, "TTL", true);
				msgRx.forwardNum = Integer.parseInt( ttl.substring("TTL:".length()) );

				String con = findItemStr(items, "0:", true).substring("0:".length());
//                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//                    msgRx.content = Base64.getEncoder().encode(con.getBytes());
//                }
				msgRx.content = new BigInteger(con, 16).toByteArray();

                mMessageListener.receiveMsg(msgRx);
			}
			if ( recvData.contains("!ACK") && mMessageListener != null) {
				String[] items = recvData.split(" "); // 使用空格作为分隔符拆分字符串
				Logger.d("onSucceed !ACK " + findItemStr(items, "!ACK", false));
				Logger.d("onSucceed !ACK " + findItemStr(items, "NODE", false));
				Logger.d("onSucceed !ACK " + findItemStr(items, "TTL", true));
				RecvMessage msgAck = new RecvMessage();
				msgAck.nodeAddress = Integer.parseInt(findItemStr(items, "NODE", false));
				String ttl = findItemStr(items, "TTL", true);
				msgAck.forwardNum = Integer.parseInt( ttl.substring("TTL:".length()) );
				mMessageListener.receiveMsg(msgAck);
			}
		}
	}

	private String findItemStr(String[] items, String item, boolean afterColonValOrNextItemVal) {
		for (int i = 0; i < items.length; i++) {
			Logger.d("======items========" + items[i]);
			if (item.contains(items[i]) && afterColonValOrNextItemVal) {//TTL:11
				return items[i];
			}
			if (item.equals(items[i]) && (i + 1) < items.length) {//to 00
				return items[i + 1];
			}
		}
		return "0";
	}

	@Override
	public void onFail(byte[] data, int len, int count) {

	}

	@Override
	public void onTimeOut() {

	}

	LoraDataListener loraDataListener;

	public void setLoraDataListener(LoraDataListener loraDataListener) {
		this.loraDataListener = loraDataListener;
	}

	public interface LoraDataListener {
		void loraDataRTNum(int sendNum, int recvNum);
	}

}
